#include "System.h"


void FPGA_BlastConfigBytes(BYTE *Data,WORD Count);

static uint8_t ConfigBuf[256];

int8_t FPGA_Config(char * Filename)
{
	uint32_t i;
    FRESULT FS_Error;
	FIL  MyFile;
	uint32_t BytesRead;
	uint8_t Junk = 0;
uint32_t BytesSent = 0;

	FS_Error = f_open(&MyFile,Filename,FA_READ);

	   if(FS_Error != FR_OK)
	     {
	    	 return CONFIG_ERROR_FILE_NOT_FOUND;
	     }

	  SetLED_BlinkRate(25);

	  PROG_B_INACTIVE;

	   //We need to make these speed indepedent some day.....
	  for(i=0;i<10000;i++)
	  	{
	  	}
	   //First Bring the PROG_B low
	   PROG_B_ACTIVE;
	  	for(i=0;i<20000;i++)
	  	{
	  	}
	  	PROG_B_INACTIVE;

	  	i = 0;
	  	while(INIT_B_STATE == 0)
	  		{
	  			i++;
	       		if(i>800000)
	  			{
	       		 SetLED_BlinkRate(1000);
	  				return CONFIG_ERROR_INIT_NOT_HIGH;
	  			}
	  		}
	  	//Read and blast until there is nothing left in the file
	  	BytesSent = 0;
	  	do
	  	{
	  		f_read(&MyFile,&ConfigBuf[0],256, &BytesRead);
	    	FPGA_BlastConfigBytes(&ConfigBuf[0],BytesRead);
	    	BytesSent+=BytesRead;
	  	}while(BytesRead==256);

	  	 f_close(&MyFile);

		for(i=0;i<255;i++)
				{
			    	//Keep Sending CCLKs until done goes high
						FPGA_BlastConfigBytes(&Junk,1);
						if(DONE_STATE > 0)
						{
							//Per Configuration Guide, send some extra clocks after config is Done
							FPGA_BlastConfigBytes(&Junk,1);
							FPGA_BlastConfigBytes(&Junk,1);
							FPGA_BlastConfigBytes(&Junk,1);
							FPGA_BlastConfigBytes(&Junk,1);
							SetLED_BlinkRate(LED_ALWAYS_ON);
							return CONFIG_OK;
						}
				}

		SetLED_BlinkRate(500);
		return CONFIG_ERROR_DONE_NOT_HIGH;
}


void FPGA_BlastConfigBytes(BYTE *Data,WORD Count)
{
	WORD i,j;
	BYTE DataOut;
	uint8_t Mask;
	DIN_INACTIVE;
	CCLK_INACTIVE;

	for(i=0;i<Count;i++)
	{
		DataOut = Data[i];
		Mask = 0x80;

		for(j=0;j<8;j++)
		{
			if((DataOut & Mask)>0)
				DIN_ACTIVE;
			else
				DIN_INACTIVE;

			CCLK_ACTIVE;
			CCLK_INACTIVE;

			Mask = Mask >> 1;
		}
	}
}

